#include <windows.h>
#include <stdio.h>
#include "Header.h"

int main()
{
    IDog* lpDog = nullptr;
    ICat* lpCat = nullptr;
    IPig* lpPig = nullptr;
    IUnknown* lpUnknown = nullptr;
    HRESULT hResult;

    CoInitialize(nullptr);

    do
    {
        hResult = CoGetClassObject(CLSID_ANIMALS, CLSCTX_INPROC, nullptr,
            IID_IUnknown, (void**)&lpUnknown);
        if (S_OK != hResult) break;

        hResult = CoGetClassObject(CLSID_ANIMALS, CLSCTX_INPROC, nullptr,
            IID_IDog, (void**)&lpDog);
        if (S_OK != hResult) break;

        hResult = CoCreateInstance(CLSID_ANIMALS, nullptr, CLSCTX_INPROC,
            IID_ICat, (void**)&lpCat);
        if (S_OK != hResult) break;

        hResult = CoCreateInstance(CLSID_ANIMALS, nullptr, CLSCTX_INPROC,
            IID_IPig, (void**)&lpPig);
        if (S_OK != hResult) break;

        lpDog->Woof((const unsigned char*)"Hello\r\n");
        lpCat->Meow((const unsigned char*)"Hello\r\n");
        lpPig->Oink((const unsigned char*)"Hello\r\n");

        lpCat->Meow(nullptr);

        ISupportErrorInfo* lpSupportErrorInfo = nullptr;
        lpCat->QueryInterface(IID_ISupportErrorInfo, (void**)&lpSupportErrorInfo);
        if (lpSupportErrorInfo)
        {
            hResult = lpSupportErrorInfo->InterfaceSupportsErrorInfo(IID_ICat);
            if (hResult == S_OK)
            {
                IErrorInfo* lpIErrorInfo = NULL;
                GetErrorInfo(0, &lpIErrorInfo);
                BSTR BStr;
                GUID Guid;
                DWORD dwId;
                lpIErrorInfo->GetDescription(&BStr);
                SysFreeString(BStr);
                lpIErrorInfo->GetGUID(&Guid);
                lpIErrorInfo->GetHelpContext(&dwId);
                lpIErrorInfo->GetHelpFile(&BStr);
                SysFreeString(BStr);
                lpIErrorInfo->GetSource(&BStr);
                SysFreeString(BStr);
                lpIErrorInfo->Release();
            }
            lpSupportErrorInfo->Release();
        }

    } while (FALSE);

    if (lpPig)
    {
        lpPig->Release();
    }

    if (lpCat)
    {
        lpCat->Release();
    }

    if (lpDog)
    {
        lpDog->Release();
    }

    if (lpUnknown)
    {
        lpUnknown->Release();
    }

    CoFreeUnusedLibraries();

    CoUninitialize();

    return 0;
}